package com.dream.mqpushserver.netty;

import com.alibaba.fastjson.JSON;
import io.netty.buffer.ByteBuf;

import java.nio.ByteBuffer;
import java.util.Arrays;

/**
 * @author song_
 * @Date 2020/3/26
 * @desc
 **/
public class RequestCommand {

    private RequestHeader requestHeader;

    /**
     * 消息体
     */
    private byte[] body;


    /**
     * 消息header
     */
    static class RequestHeader {

        private RequestCode code;

        private String type;

        public RequestHeader(RequestCode code, String type) {
            this.code = code;
            this.type = type;
        }

        @Override
        public String toString() {
            return "RequestHeader{" +
                    "code=" + code +
                    ", type='" + type + '\'' +
                    '}';
        }
    }

    public static RequestCommand buildRequestCommand(RequestCode code, byte[] body) {
        RequestCommand command = new RequestCommand();
        command.setBody(body);
        command.setRequestHeader(new RequestHeader(code, null));
        return command;
    }

    public static RequestCommand buildRequestCommand(ByteBuf headerData, ByteBuf body) {
        RequestCommand command = new RequestCommand();
        byte[] bytes = byteBuf2bytes(headerData);
        String s = JSON.toJSONString(bytes);
        RequestHeader requestHeader = JSON.parseObject(new String(bytes), RequestHeader.class);
        command.setRequestHeader(requestHeader);
        byte[] bodyBytes = byteBuf2bytes(body);
        command.setBody(bodyBytes);
        return command;
    }

    public static byte[] byteBuf2bytes(ByteBuf byteBuf) {
        byte[] bytes = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(bytes);
        return bytes;
    }

    /**
     * 数据格式
     * totalLength | headerLength | headerData | body
     * 4          |  4           |            |
     * totalLength = headerLength + headerData.length + body.length
     *
     * @return
     */
    public ByteBuffer buildBytes() {
        // headerLength
        int length = 4;

        byte[] headerData = convert2Bytes(this.requestHeader);
        // headerDataLength
        length += headerData.length;

        if (this.body != null) {
            // body length
            length += body.length;
        }

        // 需申请 4 + length 个字节空间, 前4个字节为保存总长度
        ByteBuffer byteBuffer = ByteBuffer.allocate(4 + length);

        byteBuffer.putInt(length);
        byteBuffer.putInt(headerData.length);
        byteBuffer.put(headerData);
        if (this.body != null) {
            byteBuffer.put(body);
        }
        byteBuffer.flip();

        return byteBuffer;
    }

    /**
     * 仅仅转换头部数据
     * 不含头部长度数据
     *
     * @return
     */
    public byte[] buildHeaderBytes() {
        return convert2Bytes(this.requestHeader);
    }


    public byte[] convert2Bytes(Object obj) {
        if (obj != null) {
            String s = JSON.toJSONString(obj);
            return s.getBytes();
        }
        return null;
    }


    public RequestHeader getRequestHeader() {
        return requestHeader;
    }

    public void setRequestHeader(RequestHeader requestHeader) {
        this.requestHeader = requestHeader;
    }

    public byte[] getBody() {
        return body;
    }

    public void setBody(byte[] body) {
        this.body = body;
    }

    @Override
    public String toString() {
        return "RequestCommand{" +
                "requestHeader=" + requestHeader +
                ", body=" + new String(body) +
                '}';
    }
}
